package hy.planegame

import android.content.Context
import android.graphics.Canvas
import android.os.SystemClock
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.SurfaceHolder
import android.view.SurfaceView
import hy.planegame.sprite.*
import hy.planegame.utils.d
import hy.planegame.utils.paint
import java.util.concurrent.ConcurrentHashMap
import kotlin.concurrent.thread

/**
 * Created time : 2017/8/31 15:34.
 * @author HY
 */

class GameView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) :
        SurfaceView(context, attrs, defStyleAttr), SurfaceHolder.Callback {

    private val sfh: SurfaceHolder
    private var canvas: Canvas? = null
    private val thread: Thread

    private var isStop = false
    private val gameBackground = GameBackground()
    private val boom = Boom()

    private val player = Player()

    init {
        paint.isAntiAlias = true
        paint.color = 0xff000000.toInt()
        sfh = holder


        thread = thread {

            while (!isStop) {
                drawGame()

                logic()

                SystemClock.sleep(30)
            }
        }

        thread {
            while (!isStop) {
                val enemy = Enemy()
                enemy.addBullet { bull ->
                    enemyBullet.put(bull.hashCode(), bull)
                }
                enemy.onBulletDestroy { bull ->
                    enemyBullet.remove(bull.hashCode())
                }
                enemy.onDestroy {
                    enemies.remove(enemy.hashCode())
                }

                enemies.put(enemy.hashCode(), enemy)
                SystemClock.sleep(3000)
            }
        }

        boom.stop {
            boom.reset()
        }

        player.addBullet { bull ->
            playerBullet.put(bull.hashCode(), bull)
        }

        player.onBulletDestroy { bull ->
            playerBullet.remove(bull.hashCode())
        }

    }

    @Synchronized
    private fun drawGame() {
        try {
            canvas = sfh.lockCanvas()

            gameBackground.draw(canvas)
            boom.draw(canvas)

            player.draw(canvas)

            for (entry in enemies.entries) {
                entry.value.draw(canvas)
            }

            for (entry in enemyBullet.entries) {
                entry.value.draw(canvas)
            }
            for (entry in playerBullet.entries) {
                entry.value.draw(canvas)
            }

        } catch (e: Exception) {
            d(e.javaClass.simpleName, e)
        } finally {
            if (null != canvas)
                sfh.unlockCanvasAndPost(canvas)
        }
    }

    private fun logic() {
        gameBackground.logic()
        boom.logic()
        player.logic()



        for (entry in enemies.entries) {
            entry.value.logic()
        }

        for (entry in enemyBullet.entries) {
            entry.value.logic()
        }

        for (entry in playerBullet.entries) {
            entry.value.logic()
        }

        for (entry in enemies.entries) {
            for (mutableEntry in playerBullet) {
                if (entry.value.isCollision(mutableEntry.value)) {
                    entry.value.destroy()
                    mutableEntry.value.destroy()
                }
            }
        }
    }

    //    private var isInRange = false
    override fun onTouchEvent(event: MotionEvent?): Boolean {
        event ?: return super.onTouchEvent(event)
//        isInRange = false
        when (event.action) {
            MotionEvent.ACTION_DOWN -> {
//                if (!boom.isBooming)
//                    boom.start(event.x.toInt(), event.y.toInt())
//                isInRange =
                return true
            }
            MotionEvent.ACTION_MOVE -> {
                if (player.isInRange(event.x.toInt(), event.y.toInt()))
                    player.moveTo(event.x.toInt(), event.y.toInt())
                return true
            }
        }

        return super.onTouchEvent(event)
    }

    override fun surfaceChanged(holder: SurfaceHolder?, format: Int, width: Int, height: Int) {
    }

    override fun surfaceDestroyed(holder: SurfaceHolder?) {
        isStop = true
    }

    override fun surfaceCreated(holder: SurfaceHolder?) {
        isStop = false
        thread.start()
    }

    companion object {
        /**
         * 难点：
         * 在对集合进行增加或者删除元素时，会出现 java.util.ConcurrentModificationException
         * 使用CopyOnWriteArrayList代替ArrayList
         * 或者使用 ConcurrentHashMap
         *
         * @see  java.util.ConcurrentModificationException
         */

        private val playerBullet = ConcurrentHashMap<Int, Bullet>()
        private val enemies = ConcurrentHashMap<Int, Enemy>()
        private val enemyBullet = ConcurrentHashMap<Int, EnemyBullet>()
//        private val playerBullet = ConcurrentSkipListSet<Bullet>()
    }
}